package com.sczmgk.track.httpUtils;

import android.content.Context;

import com.google.gson.Gson;
import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.HttpHandler;
import com.lidroid.xutils.http.RequestParams;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;
import com.lidroid.xutils.http.client.HttpRequest;
import com.lidroid.xutils.http.client.multipart.HttpMultipartMode;
import com.lidroid.xutils.http.client.multipart.MultipartEntity;
import com.lidroid.xutils.http.client.multipart.content.ContentBody;
import com.lidroid.xutils.http.client.multipart.content.FileBody;
import com.lidroid.xutils.http.client.multipart.content.StringBody;
import com.sczmgk.track.MyApp;
import com.sczmgk.track.entity.base.BaseEntity;
import com.sczmgk.track.test.MyCallback;
import com.sczmgk.track.utils.MyLog;
import com.sczmgk.track.utils.Tools;

import org.apache.http.entity.StringEntity;
import org.apache.http.protocol.HTTP;
import org.json.JSONObject;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import static com.sczmgk.track.MyApp.httpUtils;


/**
 * Created by Administrator on 2017/3/8.
 */

public class MyHttp {
    private static final boolean isOld = false;

    private static final String TAG = MyHttp.class.getSimpleName();

    /**
     * 返回的结果没有错误
     */
    public static final int NO_ERROR = 0;

    public static final int GET = 1;
    public static final int POST = 2;
    public static final int UPLOAD_FILE = 3;
    private static HttpHandler<String> handler;


    public static void cancle() {
        if (handler != null) {
            handler.cancel();
            handler = null;
        }
    }


    /**
     * @param context
     * @param filePath
     * @param url
     * @param dataMap
     * @param fileType
     * @param reqType
     * @param isNeedCache
     * @param cacheKey
     * @param callback
     */
    public static void requestDataT(final Context context, final String url, final int reqType, final List<String> filePath, final Map<String, Object> dataMap, final Map<String, Object> fileType, final boolean isNeedCache, final String cacheKey,
                                    final MyCallback callback) {
        handler = null;
        RequestParams params = new RequestParams("UTF-8");
        params.setHeader("Cache-Control", "no-cache");
        params.setHeader("Pragrma", "no-cache");
        params.setHeader("expires", "0");
        switch (reqType) {
            case GET:

                break;
            case POST:
                setParams(params, getDataJson(dataMap).toString());
                MyLog.d(TAG, "请求的URL: " + url);
                MyLog.i(TAG, "请求的json串： " + getDataJson(dataMap).toString());
                handler = httpUtils.send(HttpRequest.HttpMethod.POST, url, params, new RequestCallBack<String>() {
                    @Override
                    public void onSuccess(ResponseInfo<String> responseInfo) {
                        //解析数据
                        String result = responseInfo.result;
                        Gson gson = new Gson();
                        try {
                            BaseEntity temp = gson.fromJson(result, BaseEntity.class);
                            MyLog.d(TAG, "返回的数据------->>>: " + result);
                            switch (temp.code) {
                                case 1:
                                    //1.需要取得结果
                                    if (temp.data != null && !Tools.isEmpty(temp.data.toString())) {
                                        if (callback != null) {
                                            Object o = gson.fromJson(result, getT(callback.getClass()));
                                            callback.onSuccess(o);
                                        }
                                    } else {//不需要返回结果
                                        MyLog.d(TAG, "返回的数据------->>>: data为空");
                                        callback.onSuccess();
                                    }
                                    break;
                                case 0:
                                    if (callback != null) {
                                        callback.onError(temp.msg);
                                    }
                                    break;
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            MyLog.e(TAG, "解析Json错误");
                        }
                    }

                    @Override
                    public void onFailure(HttpException error, String msg) {
                        if (callback != null) {
                            MyLog.e(TAG, "服务器错误-- 错误码： " + error.getExceptionCode() + "   msg: " + msg);
                            callback.onUnknownError();
                        }
                    }
                });
                break;
            case UPLOAD_FILE:
                //1.Base64加密图片信息
                MultipartEntity multipartEntity = new MultipartEntity(HttpMultipartMode.STRICT, null, Charset.forName(HTTP.UTF_8));
                setMultipart(params, multipartEntity, dataMap, filePath, fileType);
                MyLog.d(TAG, "请求的URL: " + url);
                MyLog.i(TAG, "请求的json串： " + getDataJson(dataMap).toString());
                httpUtils.send(HttpRequest.HttpMethod.POST, url, params, new RequestCallBack<String>() {
                    @Override
                    public void onSuccess(ResponseInfo<String> responseInfo) {
                        //解析数据
                        String result = responseInfo.result;
                        Gson gson = new Gson();
                        try {
                            BaseEntity temp = gson.fromJson(result, BaseEntity.class);
                            MyLog.d(TAG, "返回的数据------->>>: " + result);
                            switch (temp.code) {
                                case 1:
                                    //1.需要取得结果
                                    if (temp.data != null) {
                                        if (callback != null) {
                                            Object o = gson.fromJson(result, getT(callback.getClass()));
                                            callback.onSuccess(o);
                                        }
                                    } else {//不需要返回结果
                                        MyLog.d(TAG, "返回的数据------->>>: data为空");
                                        callback.onSuccess();
                                    }
                                    break;
                                case 0:
                                    if (callback != null) {
                                        callback.onError(temp.msg);
                                    }
                                    break;
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            MyLog.e(TAG, "解析Json错误");
                        }
                    }

                    @Override
                    public void onFailure(HttpException error, String msg) {
                        if (callback != null) {
                            MyLog.e(TAG, "服务器错误-- 错误码： " + error.getExceptionCode() + "   msg: " + msg);
                            callback.onUnknownError();
                        }
                    }
                });
                break;


        }

    }

    private static void setMultipart(RequestParams params, MultipartEntity multipartEntity, Map<String, Object> dataMaps, List<String> filePath, Map<String, Object> fileType) {

        String encodeJson;
        try {
            JSONObject dataJsonData = null;
            JSONObject fileTypeJsonData = null;

            if (dataMaps != null) {

                dataJsonData = getDataJson(dataMaps);
            }
            if (fileType != null) {

                fileTypeJsonData = getDataJson(fileType);
            }

            JSONObject jo = new JSONObject();
            jo.put("filetypekey", fileTypeJsonData);
            jo.put("filedatakey", dataJsonData);
            String toString = jo.toString();

            MyLog.d(TAG, "文件上传信息：" + toString);
//            encodeJson = Base64.encodeToString(toString.getBytes("utf-8"), Base64.NO_WRAP).trim();// 自定义Base64lNo_WRAP是设置base64字符串里没有换行符

            ContentBody contentBody = new StringBody(toString);
            multipartEntity.addPart("datas", contentBody);

            for (String s : filePath) {
                MyLog.i(TAG, "filePath: " + s);
                if (s != null) {
                    File file = new File(s);
                    String[] split = s.split("/");
                    String fileName = split[split.length - 1];
                    FileBody file2 = new FileBody(file);

                    multipartEntity.addPart(fileName, file2);
                }
            }

            params.setBodyEntity(multipartEntity);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 取得Context的数据
     *
     * @return context 返回 json 对象
     */
    private static JSONObject getContextJson() {
        String imei = MyApp.imei;
        int userid = MyApp.loginUserUid;
        JSONObject result = null;
        JSONObject param = new JSONObject();
        try {
            param.put("imei", imei);
            param.put("uid", ((userid == 0 || userid == -1) ? 0 : userid));
            result = param;
        } catch (Exception e) {
        }
        return result;
    }

    /**
     * 设置请求参数post,put
     *
     * @param params
     * @param requestJson
     */
    private static void setParams(RequestParams params, String requestJson) {
        try {
            params.setContentType("application/json");
            StringEntity stringEntity = new StringEntity(requestJson, "UTF-8");
            params.setBodyEntity(stringEntity);
        } catch (UnsupportedEncodingException e) {
            MyLog.e(TAG, e.getMessage());
            e.printStackTrace();
        }
    }


    /**
     * 下载文件 的方法
     *
     * @param url
     * @param target   存储位置
     * @param callback
     */
    public static void downloadFile(String url, String target, RequestCallBack<File> callback) {
        MyLog.d(TAG, "下载图片的URL: " + url + "    目标路径: " + target);
        HttpUtils httpUtils = new HttpUtils();
        httpUtils.download(url, target, callback);
    }

    private void addPart(List<String> filePath) {


    }

    /**
     * 生成获取会话密钥data原数据
     *
     * @return 未加密的json字符串
     */
    private static String getSessionKeyDataJson() {
        String result = "";
        String imei = MyApp.imei;
        JSONObject param = new JSONObject();
        try {
            param.put("imei", imei);
            String randomCode = getRandomCode();
            MyApp.randomCode = randomCode;
            param.put("randomcode", randomCode);
            result = param.toString();
        } catch (Exception e) {
            MyLog.e(TAG, "生成取密钥的data原字符串错误");
        }
        MyLog.d(TAG, "获取密钥 data字符串 : " + result);
        return result;
    }

    /**
     * 生成24位数字的随机数作为id
     *
     * @return 24位的随机码： 5d2fd5564155414564212sa
     */
    public static String getRandomCode() {
        String uuid = UUID.randomUUID().toString();
        uuid = uuid.replace("-", "");
        return uuid.substring(0, 24);
    }


    /**
     * 取得会话密钥的回调接口
     */
    public interface onGetSessionKeyCallback {
        /**
         * 取得会话密钥时回调
         */
        void onGetSessionKey();

        /**
         * 取会话密钥错误回调
         */
        void onGetSessionKeyError();
    }

    /**
     * 生成请求的Data原数据
     *
     * @param dataMaps 数据集合
     * @return json字符串
     */
    private static JSONObject getDataJson(Map<String, Object> dataMaps) {
        JSONObject result = null;
        JSONObject param = new JSONObject();
        if (dataMaps != null) {
            try {
                for (Map.Entry<String, Object> entry : dataMaps.entrySet()) {
                    if (entry.getKey().equals("file")) {
                        param.put("file", new File((String) entry.getValue()));

                    }
                    {
                        param.put(entry.getKey(), entry.getValue());
                    }
                }
                result = param;

            } catch (Exception e) {
                MyLog.e(TAG, "生成请求Data的json原字符串 错误！！");
            }
        } else {
            result = new JSONObject();
        }
        return result;
    }


    public static void requestFromJson(Context context, String url, String rawJson, int requestType, MyCallback myCallback) {

        //TODO
    }


    /**
     * MD5加密
     *
     * @param plaintext 明文
     * @return ciphertext 密文
     */
    public final static String encrypt(String plaintext) {
        char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'a', 'b', 'c', 'd', 'e', 'f'};
        try {
            byte[] btInput = plaintext.getBytes();
            // 获得MD5摘要算法的 MessageDigest 对象
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            // 使用指定的字节更新摘要
            mdInst.update(btInput);
            // 获得密文
            byte[] md = mdInst.digest();
            // 把密文转换成十六进制的字符串形式
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            return "error";
        }
    }


    /**
     * 通过反射得到实例（取得父类的泛型得到实例 ）
     *
     * @return
     */
    public static Class getT(Class clazz) {
        //1.取得当前运行的clss（传入M 的类）

        //2.取得父类的类型（也就是本类）
        Type superclass = clazz.getGenericSuperclass();
        //3.判断本类是否支持泛型
        if (superclass instanceof ParameterizedType) {
            Type[] actualTypeArguments = ((ParameterizedType) superclass).getActualTypeArguments();
            //取得第一个就是实际类型
            Type actualTypeArgument = actualTypeArguments[0];
            //强转成字节码
            Class c = (Class) actualTypeArgument;
            //得到实例
            try {
                return c;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        return null;
    }
}
